
#ifndef _FAST_VEC_H
#  define _FAST_VEC_H

#  include <config.h>
#  include <vector.h>
#  include <stdio.h>

/* These are the data definitions. */

#  ifndef _VECT_DATA_DECS
#    define _VECT_DATA_DECS
typedef struct vm_vector {

  double x;
  double y;
  double z;
  double w;

} vm_vector __attribute__((aligned (16)));

#    define X_AXIS(V) V.x = 1; V.y = 0; V.z = 0; V.w = 0;
#    define Y_AXIS(V) V.x = 0; V.y = 1; V.z = 0; V.w = 0;
#    define Z_AXIS(V) V.x = 0; V.y = 0; V.z = 1; V.w = 0;
#    define W_AXIS(V) V.x = 0; V.y = 0; V.z = 0; V.w = 1;
#    define ZERO(V)   V.x = 0; V.y = 0; V.z = 0; V.w = 0;

extern vm_vector UNIT_X;
extern vm_vector UNIT_Y;
extern vm_vector UNIT_Z;
extern vm_vector UNIT_W;

#  endif

/* The function declarations. */

void   _vm_asm_add(vm_vector *, vm_vector *);
void   _vm_asm_sub(vm_vector *, vm_vector *);
double _vm_asm_dot(vm_vector *, vm_vector *);
void   _vm_asm_scale(vm_vector *, double *, vm_vector *);
double _vm_asm_magnitude(vm_vector *);
void   _vm_asm_norm(vm_vector *, vm_vector *);
void   _vm_asm_project(vm_vector *, vm_vector *, vm_vector *);

#  ifdef _ONLY_FAST_VECT
#    define DEBUG() fprintf(stderr, "ASM_FUNC\n");
#    define vm_add(v1, v2)         DEBUG(); _vm_asm_add(v1, v2)
#    define vm_sub(v1, v2)         DEBUG(); _vm_asm_sub(v1, v2)
#    define vm_dot(v1, v2)         DEBUG(); _vm_asm_dot(v1, v2)
#    define vm_scale(v1, fact, v2) DEBUG(); _vm_asm_scale(v1, fact, v2)
#    define vm_magnitude(v1)       DEBUG(); _vm_asm_magnitude(v1)
#    define vm_norm(v1, v2)        DEBUG(); _vm_asm_norm(v1, v2)
#    define vm_project(v1, v2, v3) DEBUG(); _vm_asm_project(v1, v2, v3)
#  endif

#endif
